home *** CD-ROM | disk | FTP | other *** search
Text File | 1995-03-12 | 9.5 KB | 315 lines | [TEXT/CWIE] |
- // LConsoleAttachment.h - Attachment which pumps events through SIOUX.
- /******************************************************************************\
- Copyright (c) 1995 by Ken Badertscher (KenBad@aol.com). All Rights Reserved.
-
- Permission to use, copy, modify, distribute and sell this software and its
- documentation for any purpose is hereby granted without fee, provided that
- the above copyright notice appear in all copies and that both that copyright
- notice and this permission notice appear in supporting documentation.
- Ken Badertscher makes no representations about the suitability of this software
- for any purpose. It is provided "as is" without express or implied warranty.
-
- Mail kudos & brickbats to KenBad@aol.com.
-
- History:
- 95-10-30 kbad Added command mapping to let SIOUX use app menus.
- 95-10-15 kbad Added auto-close flag
- 95-03-12 kbad Created
-
- TODO:
- \******************************************************************************/
-
- #ifndef LCONSOLEATTACHMENT_H
- #include "LConsoleAttachment.h"
- #endif
-
- #include <SIOUX.h>
- #include <LMenuBar.h>
- #include <Processes.h>
- #include <Windows.h>
-
- // Danger, Will Robinson... these functions are not explicitly exported
- // by SIOUX (though they should be!). Alternatives involve gross hackery.
- //
- extern "C" {
-
- // SIOUXIsAppWindow could be circumvented if it was assumed that all other
- // app windows are PowerPlant windows. Then LConsoleAttachment::SIOUXIsFront
- // could look up the refCon in the window list.
- //
- Boolean SIOUXIsAppWindow(const WindowRef);
-
- // Note that even without the following, the command-key event hackery in
- // LConsoleAttachment::CommandKeyEvent should force SIOUX to do the right thing,
- // albeit much less cleanly.
- //
- void SIOUXDoEditCut();
- void SIOUXDoEditCopy();
- void SIOUXDoEditPaste();
- void SIOUXDoEditClear();
- void SIOUXDoEditSelectAll();
- void SIOUXDoSaveText();
- void SIOUXDoPrintText();
- void SIOUXUpdateScrollbar();
-
- } // extern "C"
-
-
- // Global decls
- //==============================================================================
-
- // Default console attachment, useful if no customization is needed.
- //
- LConsoleAttachment gConsoleAttachment;
-
- // Local decls
- //==============================================================================
-
- // StFlushSIOUX
- //==============================================================================
-
- StFlushSIOUX::~StFlushSIOUX()
- {
- /*----------------------------------------------------------------------------*\
- work around flush manipulator not updating scrollbar
- \*----------------------------------------------------------------------------*/
- ::SIOUXUpdateScrollbar();
- }
-
-
- // LConsoleAttachment
- //==============================================================================
-
-
- LConsoleAttachment::LConsoleAttachment(StringPtr title,
- EAutoClose close, EAskSave askSave)
- : LAttachment(msg_AnyMessage), mTitleSet(false), mCommandsCached(false)
- {
- /*----------------------------------------------------------------------------*\
- default c'tor
- \*----------------------------------------------------------------------------*/
- // set up SIOUX behavior
- //
- SIOUXSettings.initializeTB = SIOUXSettings.setupmenus = false;
- SIOUXSettings.autocloseonquit = (close==kAutoClose);
- SIOUXSettings.asktosaveonclose = (askSave==kAskSave);
-
- // set console window title
- // If this isn't set here, a default title is set when the window
- // is first shown.
- if (title)
- mTitle = title;
- }
-
-
- LConsoleAttachment::~LConsoleAttachment()
- {
- /*----------------------------------------------------------------------------*\
- d'tor
- \*----------------------------------------------------------------------------*/
- }
-
-
- LConsoleAttachment::LConsoleAttachment(const LConsoleAttachment&)
- { // private, unimplemented
- /*----------------------------------------------------------------------------*\
- copy c'tor
- \*----------------------------------------------------------------------------*/
- }
-
-
- LConsoleAttachment& LConsoleAttachment::operator=(const LConsoleAttachment&)
- { // private, unimplemented
- /*----------------------------------------------------------------------------*\
- assignment
- \*----------------------------------------------------------------------------*/
- return *this;
- }
-
-
- void LConsoleAttachment::ExecuteSelf(MessageT inMessage, void *ioParam)
- {
- /*----------------------------------------------------------------------------*\
- Dispatch the message.
- If it's an event message, always pass it to SIOUX.
- Only pass commands & cursor adjustments when SIOUX window is frontmost.
- \*----------------------------------------------------------------------------*/
- mExecuteHost = true;
- if (inMessage == msg_Event)
- {
- DispatchEvent(*(EventRecord *)ioParam);
- }
- else if (SIOUXIsFront())
- {
- switch (inMessage)
- {
- case msg_CommandStatus:
- FindCommandStatus(*(SCommandStatus *)ioParam);
- break;
-
- case msg_AdjustCursor:
- AdjustCursor(*(EventRecord *)ioParam);
- break;
-
- //case cmd_Close:
- case cmd_Save: ::SIOUXDoSaveText(); break;
- case cmd_Print: ::SIOUXDoPrintText(); break;
- //case cmd_Undo:
- case cmd_Cut: ::SIOUXDoEditCut(); break;
- case cmd_Copy: ::SIOUXDoEditCopy(); break;
- case cmd_Paste: ::SIOUXDoEditPaste(); break;
- case cmd_Clear: ::SIOUXDoEditClear(); break;
- case cmd_SelectAll: ::SIOUXDoEditSelectAll(); break;
-
- // Pass other potential menu commands through as key commands
- default: ObeyCommand(inMessage, ioParam);
- }
- }
- }
-
- void LConsoleAttachment::FindCommandStatus(const SCommandStatus &status)
- {
- /*----------------------------------------------------------------------------*\
- Enable SIOUX-related menu commands when console window is frontmost.
- \*----------------------------------------------------------------------------*/
- EventRecord e;
- switch (status.command)
- {
-
- // Commands handled directly by SIOUX:
- //
- //case cmd_Close:
- case cmd_Save:
- case cmd_Print:
- //case cmd_Undo:
- case cmd_Cut:
- case cmd_Copy:
- case cmd_Paste:
- case cmd_Clear:
- case cmd_SelectAll:
- *status.enabled = true;
- *status.usesMark = false;
- mExecuteHost = false;
- break;
-
- // Other commands with key equivalents:
- //
- default:
- if (CommandKeyEvent(status.command, e))
- {
- *status.enabled = true;
- *status.usesMark = false;
- mExecuteHost = false;
- }
- }
- }
-
-
- Boolean LConsoleAttachment::CommandKeyEvent(CommandT inCommand, EventRecord& e)
- {
- /*----------------------------------------------------------------------------*\
- Create a command key event for a menu command.
- This will be invoked only if the console window is frontmost,
- meaning that menus are up.
- \*----------------------------------------------------------------------------*/
- if (inCommand > kNumCommands) e.message = 0;
- else
- {
- if (!mCommandsCached)
- {
- // Set up command key message cache.
- // Not done in constructor, because menus might not be up yet.
- //
- for (int i = 0; i < kNumCommands; i++)
- {
- mCommandKeyEvent[i] = 0;
- ResIDT menuID;
- MenuHandle menuH;
- Int16 menuItem;
- LMenuBar::GetCurrentMenuBar()->
- FindMenuItem(i, menuID, menuH, menuItem);
- if (menuH)
- {
- // Look up key equivalent in menu.
- // If it's not a special char (submenu, script code,
- // ICON, SICN), set the event message for that command.
- //
- short cmdChar;
- ::GetItemCmd(menuH, menuItem, &cmdChar);
- if (!cmdChar && i == cmd_Clear)
- mCommandKeyEvent[i] = 0x3308; // vkey | char_Backspace;
- else if (cmdChar < 0x1b || 0x1e < cmdChar)
- mCommandKeyEvent[i] = cmdChar;
- }
- }
- mCommandsCached = true;
- }
-
- // Fill in the event record for this command.
- //
- e.what = keyDown;
- e.modifiers = (inCommand == cmd_Clear) ? 0 : cmdKey;
- e.message = mCommandKeyEvent[inCommand];
- }
-
- return (e.message != 0);
- }
-
- void LConsoleAttachment::AdjustCursor(const EventRecord &inMacEvent)
- {
- /*----------------------------------------------------------------------------*\
- Let SIOUX adjust the cursor when the console is frontmost
- \*----------------------------------------------------------------------------*/
- EventRecord e = inMacEvent;
- e.what = nullEvent;
- ::SIOUXHandleOneEvent(&e);
- mExecuteHost = false; // never execute in host--it will always set an arrow
- }
-
- void LConsoleAttachment::DispatchEvent(const EventRecord& inMacEvent)
- {
- /*----------------------------------------------------------------------------*\
- SIOUX event pump
- \*----------------------------------------------------------------------------*/
- #ifndef OM_NoExplicitTemplates
- EventRecord *evptr = const_cast<EventRecord *>(&inMacEvent);
- #endif
- mExecuteHost = !::SIOUXHandleOneEvent(evptr);
- }
-
- void LConsoleAttachment::ObeyCommand(CommandT inCommand, void *ioParam)
- {
- /*----------------------------------------------------------------------------*\
- Translate menu commands to key commands for SIOUX.
- \*----------------------------------------------------------------------------*/
- #pragma unused (ioParam)
- EventRecord e;
- if (CommandKeyEvent(inCommand, e))
- mExecuteHost = !::SIOUXHandleOneEvent(&e);
- }
-
- Boolean LConsoleAttachment::SIOUXIsFront()
- {
- /*----------------------------------------------------------------------------*\
- Return true if SIOUX window is frontmost.
- The first time it is frontmost, set its title.
- \*----------------------------------------------------------------------------*/
- WindowRef frontWind = ::FrontWindow();
- Boolean result = (frontWind && ::SIOUXIsAppWindow(frontWind));
- if (result && !mTitleSet)
- {
- if (mTitle.Length() == 0)
- {
- ProcessSerialNumber psn;
- ::GetCurrentProcess(&psn);
- ProcessInfoRec pinfo;
- ::GetProcessInformation(&psn, &pinfo);
- mTitle = pinfo.processName;
- mTitle += "\p Console";
- }
-
- ::SIOUXSetTitle(mTitle);
- mTitleSet = true;
- }
- return result;
- }